using System;
#if !SANDBOX
using System.Reflection;
#endif
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
using PS.Practices.SiteBuilder.Features.Schema;
using WebPart=System.Web.UI.WebControls.WebParts.WebPart;

namespace PS.Practices.Util
{
    public static class WebPartUtil
    {
        public static void SetListViewWebPartView(ListViewWebPart lvwp, SPView view, uint toolbar, SPLimitedWebPartManager manager)
        {
            string listId = view.ParentList.ID.ToString("B").ToUpper();
            string viewId = view.ID.ToString("B").ToUpper();
            
            uint flags;
            SPWebPartManager spwWpMgr = UnwrapSPWebPartManager(manager);
            if (spwWpMgr != null)
            {
                SPWebPartCollection coll = UnwrapSPWebPartCollection(spwWpMgr);
                if (coll != null)
                    ApplyViewToListWebPart(coll, lvwp.StorageKey.ToString("B").ToUpper(),
                                           listId, viewId, toolbar, out flags);
            }
        }

        private static void ApplyViewToListWebPart(SPWebPartCollection coll, string storageKey, string listId, string viewId, uint toolbarType, out uint flags)
        {
#if !SANDBOX
            Type t = typeof(SPWebPartCollection);
            object[] args = new object[] {storageKey, listId, viewId, toolbarType, null};
            t.InvokeMember("ApplyViewToListWebPart", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod,
                           null, coll, args
                );
            flags = (uint) args[4];
#else
            flags = 0;
#endif
        }

        private static SPWebPartCollection UnwrapSPWebPartCollection(SPWebPartManager spwWpMgr)
        {
#if !SANDBOX
            Type t = typeof(SPWebPartManager);
            return t.InvokeMember("SPWebParts", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty,
                                  null, spwWpMgr, null) as SPWebPartCollection;
#else
            return null;
#endif
        }

        private static SPWebPartManager UnwrapSPWebPartManager(SPLimitedWebPartManager manager)
        {
#if !SANDBOX
            Type t = typeof(SPLimitedWebPartManager);
            return t.InvokeMember("WebPartManager", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty, null,
                                  manager, null) as SPWebPartManager;
#else
            return null;
#endif
        }

        public static bool SetWPProperty(WebPart part, string name, string value, SPWeb web)
        {
#if !SANDBOX
            Type t = part.GetType();
            PropertyInfo pi = t.GetProperty(name);
            if (pi == null || !pi.CanWrite)
                return false;

            string val = ParserUtil.ReplaceLiveFields(value, null, web);
            //try
            {
                pi.SetValue(part, val, null);
            }
            //catch (Exception)
            {
            }
            return true;
#else
            return true;
#endif
        }
    }
}